hvm: Clean up CPUID 0x80000001 emulation. Filter out RDTSCP feature
authorKeir Fraser <keir.fraser@citrix.com>
Thu, 22 Nov 2007 10:33:10 +0000 (10:33 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Thu, 22 Nov 2007 10:33:10 +0000 (10:33 +0000)
and emulate with #UD on AMD.
Signed-off-by: Keir Fraser <keir.fraser@eu.citrix.com>
xen/arch/x86/hvm/svm/emulate.c
xen/arch/x86/hvm/svm/svm.c
xen/arch/x86/hvm/vmx/vmx.c
xen/include/asm-x86/hvm/svm/emulate.h

index a0c3c5cc3b643d13404cdf49c9aec912911aabf8..f22fd1cc17d0d6ee0033bb204fcf8cc1790a530b 100644 (file)
@@ -348,8 +348,6 @@ MAKE_INSTR(WBINVD, 2, 0x0f, 0x09);
 MAKE_INSTR(CPUID,  2, 0x0f, 0xa2);
 MAKE_INSTR(RDMSR,  2, 0x0f, 0x32);
 MAKE_INSTR(WRMSR,  2, 0x0f, 0x30);
-MAKE_INSTR(RDTSC,  2, 0x0f, 0x31);
-MAKE_INSTR(RDTSCP, 3, 0x0f, 0x01, 0xf9);
 MAKE_INSTR(CLI,    1, 0xfa);
 MAKE_INSTR(STI,    1, 0xfb);
 MAKE_INSTR(RDPMC,  2, 0x0f, 0x33);
@@ -383,8 +381,6 @@ static const u8 *opc_bytes[INSTR_MAX_COUNT] =
     [INSTR_CPUID]  = OPCODE_CPUID,
     [INSTR_RDMSR]  = OPCODE_RDMSR,
     [INSTR_WRMSR]  = OPCODE_WRMSR,
-    [INSTR_RDTSC]  = OPCODE_RDTSC,
-    [INSTR_RDTSCP] = OPCODE_RDTSCP,
     [INSTR_CLI]    = OPCODE_CLI,
     [INSTR_STI]    = OPCODE_STI,
     [INSTR_RDPMC]  = OPCODE_RDPMC,
index 1b5b5dfa6a1131c489c3b9d12cfc0e59e8111df9..96e380a9d6f168b5dab33744afcac874752323a6 100644 (file)
@@ -996,6 +996,7 @@ static void svm_do_no_device_fault(struct vmcb_struct *vmcb)
 /* Reserved bits EDX: [31:29], [27], [22:20], [18], [10] */
 #define SVM_VCPU_CPUID_L1_EDX_RESERVED 0xe8740400
 
+#define bitmaskof(idx)  (1U << ((idx) & 31))
 static void svm_vmexit_do_cpuid(struct vmcb_struct *vmcb,
                                 struct cpu_user_regs *regs)
 {
@@ -1022,32 +1023,23 @@ static void svm_vmexit_do_cpuid(struct vmcb_struct *vmcb,
         break;
 
     case 0x80000001:
+        /* Filter features which are shared with 0x00000001:EDX. */
         if ( vlapic_hw_disabled(vcpu_vlapic(v)) )
             __clear_bit(X86_FEATURE_APIC & 31, &edx);
-
 #if CONFIG_PAGING_LEVELS >= 3
         if ( !v->domain->arch.hvm_domain.params[HVM_PARAM_PAE_ENABLED] )
 #endif
             __clear_bit(X86_FEATURE_PAE & 31, &edx);
-
         __clear_bit(X86_FEATURE_PSE36 & 31, &edx);
 
-        /* Clear the Cmp_Legacy bit
-         * This bit is supposed to be zero when HTT = 0.
-         * See details on page 23 of AMD CPUID Specification.
-         */
-        __clear_bit(X86_FEATURE_CMP_LEGACY & 31, &ecx);
-
-        /* Make SVM feature invisible to the guest. */
-        __clear_bit(X86_FEATURE_SVME & 31, &ecx);
-        __clear_bit(X86_FEATURE_SKINIT & 31, &ecx);
-
-        __clear_bit(X86_FEATURE_OSVW & 31, &ecx);
-        __clear_bit(X86_FEATURE_WDT & 31, &ecx);
-
-        /* So far, we do not support 3DNow for the guest. */
-        __clear_bit(X86_FEATURE_3DNOW & 31, &edx);
-        __clear_bit(X86_FEATURE_3DNOWEXT & 31, &edx);
+        /* Filter all other features according to a whitelist. */
+        edx &= (0x0183f3ff | /* features shared with 0x00000001:EDX */
+                bitmaskof(X86_FEATURE_NX) |
+                bitmaskof(X86_FEATURE_LM) |
+                bitmaskof(X86_FEATURE_SYSCALL) |
+                bitmaskof(X86_FEATURE_MP) |
+                bitmaskof(X86_FEATURE_MMXEXT) |
+                bitmaskof(X86_FEATURE_FFXSR));
         break;
 
     case 0x80000007:
@@ -2293,6 +2285,7 @@ asmlinkage void svm_vmexit_handler(struct cpu_user_regs *regs)
         hvm_triple_fault();
         break;
 
+    case VMEXIT_RDTSCP:
     case VMEXIT_MONITOR:
     case VMEXIT_MWAIT:
     case VMEXIT_VMRUN:
index 14884bd9bce11dd63b421e74f5dea05011a855ac..25719967f9f8c134d7112e0a98ca7613f6732822 100644 (file)
@@ -1298,6 +1298,14 @@ static void vmx_do_cpuid(struct cpu_user_regs *regs)
     case 0x0000000A:
         eax = ebx = ecx = edx = 0;
         break;
+
+    case 0x80000001:
+        /* Only a few features are advertised in Intel's 0x80000001. */
+        ecx &= (bitmaskof(X86_FEATURE_LAHF_LM));
+        edx &= (bitmaskof(X86_FEATURE_NX) |
+                bitmaskof(X86_FEATURE_LM) |
+                bitmaskof(X86_FEATURE_SYSCALL));
+        break;
     }
 
     regs->eax = eax;
index dfc66bcaeafbeeff205d18c24cf9c9b91d9abed7..3d46490d6ea9c6c7e1545ea49f1d0ea2f57358f6 100644 (file)
@@ -47,8 +47,6 @@ enum instruction_index {
     INSTR_CPUID,
     INSTR_RDMSR,
     INSTR_WRMSR,
-    INSTR_RDTSC,
-    INSTR_RDTSCP,
     INSTR_CLI,
     INSTR_STI,
     INSTR_RDPMC,